﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web;
using System.Web.Configuration;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Xml;
using AlipaySDK.Dto.Payment;
using AlipaySDK.Helper;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Dto.Inpatient;
using User.Api.Helpers;
using User.Api.HttpClients;
using PayFailedResponse = User.Api.Dto.Inpatient.PayFailedResponse;

namespace User.Api.Controllers
{
    public class InpatientController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(InpatientController));
        private GdsfybjyWeiXinEntities _ctx;

        private static readonly object OrderNoLocker = new object();
        private static readonly object PayNotifyLocker = new object();

        protected override void Initialize(HttpControllerContext controllerContext)
        {
            _ctx = new GdsfybjyWeiXinEntities();
            base.Initialize(controllerContext);
        }

        protected override void Dispose(bool disposing)
        {
            _ctx.Dispose();
            base.Dispose(disposing);
        }

        /// <summary>
        /// 获取当前住院记录
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetInpatient")]
        public GetInpatientResponse GetInpatient(int cardId)
        {
            
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.HospCards.FirstOrDefault(x => x.CardId == cardId && x.WxUserId == azUser.UserId);

            if (card == null)
            {
                return new GetInpatientResponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到就诊卡"
                };
            }

            var inpatientListRequest = new GetInPatientHisRequest();
            inpatientListRequest.CardNo = card.CardNo;
            GetInPatientHisResponse inPatientListResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetInPatientHis", inpatientListRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                inPatientListResponse = responseMsg.Content.ReadAsAsync<GetInPatientHisResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取住院记录Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetInpatientResponse
                {
                    ResultCode = "2",
                    ResultMsg = "获取住院记录超时"
                };
            }

            if (inPatientListResponse.ResultCode != "0")
            {
                return new GetInpatientResponse
                {
                    ResultCode = "3",
                    ResultMsg = inPatientListResponse.ResultDesc
                };
            }

            var currentInpatient = inPatientListResponse.InPatientHisList
                .FirstOrDefault(x => x.IsInp == "1");
            if (currentInpatient == null)
            {
                return new GetInpatientResponse
                {
                    ResultCode = "4",
                    ResultMsg = "没有找到您的住院记录"
                };
            }

            var prepayBalance = "unknown";
            var prepayBalanceRequest = new GetIcCardHolderStateRequest();
            prepayBalanceRequest.CardNo = card.CardNo;

            GetIcCardHolderStateResponse prepayBalanceResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetIcCardHolderState", prepayBalanceRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                prepayBalanceResponse = responseMsg.Content.ReadAsAsync<GetIcCardHolderStateResponse>().Result;

                if (prepayBalanceResponse.ResultCode == "0"
                    && prepayBalanceResponse.PrepayList != null
                    && prepayBalanceResponse.PrepayList.Count > 0)
                {
                    prepayBalance = prepayBalanceResponse.PrepayList[0].Amt;
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内住院预缴金余额Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetInpatientResponse
                {
                    ResultCode = "5",
                    ResultMsg = "获取住院预缴金余额超时"
                };
            }

            //if (prepayBalanceResponse.ResultCode != "0")
            //{
            //    return new GetInpatientResponse
            //    {
            //        ResultCode = "6",
            //        ResultMsg = prepayBalanceResponse.ResultDesc
            //    };
            //}

            //if (prepayBalanceResponse.PrepayList == null
            //    || prepayBalanceResponse.PrepayList.Count == 0)
            //{
            //    return new GetInpatientResponse
            //    {
            //        ResultCode = "7",
            //        ResultMsg = "没有找到您的住院记录"
            //    };
            //}

            var billListRequest = new GetInpBillListRequest();
            billListRequest.PatientId = currentInpatient.PatientId;
            billListRequest.VisitId = currentInpatient.VisitId;
            billListRequest.BeginDate = currentInpatient.InDate;
            billListRequest.EndDate = DateTime.Today.AddDays(-1).ToString("yyyy-MM-dd");

            GetInpBillListResponse billListResponse;

            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetInpBillList", billListRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                billListResponse = responseMsg.Content.ReadAsAsync<GetInpBillListResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内住院每日费用Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetInpatientResponse
                {
                    ResultCode = "8",
                    ResultMsg = "获取住院每日费用超时"
                };
            }

            if (billListResponse.ResultCode != "0")
            {
                return new GetInpatientResponse
                {
                    ResultCode = "9",
                    ResultMsg = "获取住院每日费用超时"
                };
            }

            return new GetInpatientResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                PatientId = currentInpatient.PatientId,
                VisitId = currentInpatient.VisitId,
                InDate = currentInpatient.InDate,
                PrepayBalance = prepayBalance,
                DailyBills = billListResponse.BillInfoList.OrderByDescending(x => x.BillDate)
                .GroupBy(x => x.BillDate, x => x)
                .Select(x => new GetInpatientResponse.DailyBill
                {
                    BillDate = x.Key,
                    Costed = x.Sum(y => y.Costed.ToDecimalOrDefault()).ToString("F2"),
                    Memo = x.Count(y => y.IsChild == "1") > 0 ?
                        string.Format("其中小孩费用 {0} 元",
                            x.Where(y => y.IsChild == "1").Sum(y => y.Costed.ToDecimalOrDefault()).ToString("F2")) :
                        ""
                }).ToList()
            };
        }

        /// <summary>
        /// 获取每日住院费用
        /// </summary>
        /// <param name="patientId"></param>
        /// <param name="visitId"></param>
        /// <param name="billDate"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetDailyBill")]
        public GetDailyBillResponse GetDailyBill(string patientId, string visitId, string billDate)
        {
            var categoryRequest = new GetCategoryBillListRequest();
            categoryRequest.PatientId = patientId;
            categoryRequest.VisitId = visitId;
            categoryRequest.BillDate = billDate;
            GetCategoryBillListResponse categoryResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetCategoryBillList", categoryRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                categoryResponse = responseMsg.Content.ReadAsAsync<GetCategoryBillListResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取住院每日费用分类信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetDailyBillResponse
                {
                    ResultCode = "1",
                    ResultMsg = "获取住院每日费用分类信息超时"
                };
            }

            if (categoryResponse.ResultCode != "0")
            {
                return new GetDailyBillResponse
                {
                    ResultCode = "2",
                    ResultMsg = categoryResponse.ResultDesc
                };
            }

            var res = new GetDailyBillResponse();
            res.ResultCode = "0";
            res.ResultMsg = "";
            res.Categories = new List<GetDailyBillResponse.Category>();

            foreach (var category in categoryResponse.CategoryBillList.OrderBy(x => x.CategoryId))
            {
                var billCategory = new GetDailyBillResponse.Category
                {
                    CategoryName = category.CategoryName,
                    CategoryFee = (category.CategoryFee.ToDecimalOrDefault() / 100.0m).ToString("F2"),
                    Items = new List<GetDailyBillResponse.Item>()
                };
                res.Categories.Add(billCategory);

                var request = new GetCategoryBillDetailRequest();
                request.PatientId = patientId;
                request.VisitId = visitId;
                request.BillDate = billDate;
                request.CategoryId = category.CategoryId;

                GetCategoryBillDetailResponse response;

                try
                {
                    var httpClient = InHttpClient.GetClient();
                    var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetCategoryBillDetail", request).Result;
                    responseMsg.EnsureSuccessStatusCode();
                    response = responseMsg.Content.ReadAsAsync<GetCategoryBillDetailResponse>().Result;
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("调用院内获取住院每日费用明细信息Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                    continue;
                }

                if (response.ResultCode == "0")
                {
                    foreach (var itemInfo in response.ItemList)
                    {
                        billCategory.Items.Add(new GetDailyBillResponse.Item
                        {
                            ItemName = itemInfo.ItemName,
                            TypeName = itemInfo.ItemSpec,
                            Unit = itemInfo.ItemUnit,
                            UnitPrice = (itemInfo.ItemPrice.ToDecimalOrDefault() / 100.0m).ToString("F2"),
                            Quantity = (itemInfo.Amount.ToDecimalOrDefault() / 100.0m).ToString("F2"),
                            Price = (itemInfo.Costs.ToDecimalOrDefault() / 100.0m).ToString("F2"),
                            IsChild = "0"
                        });
                    }
                }
            }

            return res;
        }

        /// <summary>
        /// 获取住院预缴金信息
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetInpatientPrepayInfo")]
        public GetInpatientPrepayInfoResponse GetInpatientPrepayInfo(int cardId)
        {
            var azUser = AzUser.GetInApi(Request);

            var card = _ctx.HospCards.FirstOrDefault(x => x.CardId == cardId && x.WxUserId == azUser.UserId);

            if (card == null)
            {
                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到就诊卡"
                };
            }

            var inpatientListRequest = new GetInPatientHisRequest();
            inpatientListRequest.CardNo = card.CardNo;

            GetInPatientHisResponse inPatientListResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetInPatientHis", inpatientListRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                inPatientListResponse = responseMsg.Content.ReadAsAsync<GetInPatientHisResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内获取住院记录Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "2",
                    ResultMsg = "获取住院记录超时"
                };
            }

            if (inPatientListResponse.ResultCode != "0")
            {
                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "3",
                    ResultMsg = inPatientListResponse.ResultDesc
                };
            }

            var currentInpatient = inPatientListResponse.InPatientHisList
                .FirstOrDefault(x => x.IsInp == "1");
            if (currentInpatient == null)
            {
                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "4",
                    ResultMsg = "没有找到您的住院记录"
                };
            }

            var prepayBalanceRequest = new GetIcCardHolderStateRequest();
            prepayBalanceRequest.CardNo = card.CardNo;

            GetIcCardHolderStateResponse prepayBalanceResponse;
            try
            {
                var httpClient = InHttpClient.GetClient();
                var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetIcCardHolderState", prepayBalanceRequest).Result;
                responseMsg.EnsureSuccessStatusCode();
                prepayBalanceResponse = responseMsg.Content.ReadAsAsync<GetIcCardHolderStateResponse>().Result;
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("调用院内住院预缴金余额Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "5",
                    ResultMsg = "获取住院预缴金余额超时"
                };
            }

            if (prepayBalanceResponse.ResultCode != "0")
            {
                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "6",
                    ResultMsg = prepayBalanceResponse.ResultDesc
                };
            }

            if (prepayBalanceResponse.PrepayList == null
                || prepayBalanceResponse.PrepayList.Count == 0)
            {
                return new GetInpatientPrepayInfoResponse
                {
                    ResultCode = "7",
                    ResultMsg = "没有找到您的住院记录"
                };
            }

            return new GetInpatientPrepayInfoResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                PatientId = currentInpatient.PatientId,
                VisitId = currentInpatient.VisitId,
                InDate = currentInpatient.InDate,
                PrepayBalance = prepayBalanceResponse.PrepayList[0].Amt
            };
        }

        [HttpGet]
        [ActionName("CreatePrepayOrder")]
        public CreatePrepayOrderResponse CreatePrepayOrder(int cardId, string patientId, string visitId, string money)
        {
            var azUser = AzUser.GetInApi(Request);
            var card = _ctx.HospCards.FirstOrDefault(x => x.CardId == cardId && x.WxUserId == azUser.UserId);
            if (card == null)
            {
                return new CreatePrepayOrderResponse
                {
                    ResultCode = "1",
                    ResultMsg = "找不到就诊卡信息"
                };
            }

            var intMoney = money.ToDecimalOrDefault();
            if (intMoney <= 0)
            {
                return new CreatePrepayOrderResponse
                {
                    ResultCode = "2",
                    ResultMsg = "错误的充值金额"
                };
            }

            //住院患者做业务操作（例:预交、清账）前的有效性检测，检测通过后再允许业务功能的继续执行
            //var checkRequest = new OperationCheckRequest();
            //checkRequest.InpatientId = visitId;
            //checkRequest.OperType = "1";

            //OperationCheckResponse checkResponse;
            //try
            //{
            //    var httpClient = InHttpClient.GetClient();
            //    var responseMsg = httpClient.PostAsJsonAsync("HisSp/OperationCheck", checkRequest).Result;
            //    responseMsg.EnsureSuccessStatusCode();
            //    checkResponse = responseMsg.Content.ReadAsAsync<OperationCheckResponse>().Result;
            //}
            //catch (Exception ex)
            //{
            //    Logger.ErrorFormat("调用院内有效性检测Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

            //    return new CreatePrepayOrderResponse
            //    {
            //        ResultCode = "3",
            //        ResultMsg = "调用院内预交金有效性检测"
            //    };
            //}

            //if (checkResponse.ResultCode != "0")
            //{
            //    return new CreatePrepayOrderResponse
            //    {
            //        ResultCode = "4",
            //        ResultMsg = checkResponse.ResultDesc
            //    };
            //}

            var newPrepayOrder = new InpatientPrepayOrder()
            {
                CardNo = card.CardNo,
                CardType = card.CardType.ToString(),
                OpenId = azUser.OpenId,
                CreateTime = DateTime.Now,
                PayState = PrepayOrderExtensions.PayState.未付款.ToInt32().ToString(),
                OrderStatus = PrepayOrderExtensions.OrderStatus.支付中.ToInt32(),
                PrepayMoney = intMoney,
                PatientId = patientId,
                InpatientId = visitId,
                //VisitId = visitId,
                OrderNo = GenerateNewOrderNo(),
                CardName = card.PatientName,
                AliPayType = "WAP"
            };

            _ctx.InpatientPrepayOrders.Add(newPrepayOrder);
            _ctx.SaveChanges();

            // RMQ 16分钟后如果还是支付中则设置支付失败
            var payingTimeoutProducer = new OrderPayingTimeoutProducer();
            payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
            {
                OrderType = OrderType.住院预缴金订单,
                OrderId = newPrepayOrder.Id
            }, 16 * 60 * 1000);

            //组织 微信 js 支付方法 getBrandWCPayRequest 的参数

            var payFee = newPrepayOrder.PrepayMoney.GetValueOrDefault().ToInt32().ToString();
            var superOpenIds = ConfigurationManager.AppSettings["OpenIdsForPayMin"]
                .Split(" , ", StringSplitOptions.RemoveEmptyEntries);
            if (superOpenIds.Contains(newPrepayOrder.OpenId))
            {
                payFee = "0.01";
            }

            //var payRequestParam = TenpayV2Helper.GenerateWxPayParameter("住院预缴金", "IP" + newPrepayOrder.OrderNo,
            //    payFee, GetClientIp(), payStartTime, payExpireTime, "Inpatient/PaySucceed");

            var result =
                WapPayment.ComposeWapPayParameter(new ComposeWapPayRequest
                {
                    NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"] + "Inpatient/PaySucceed",
                    CallBackUrl = MessageHelper.GetCallBackUrl("/index/do-prepay-callback"),
                    MerchantUrl = "",
                    OutTradeNo = "IP" + newPrepayOrder.OrderNo,
                    Subject = "预交金缴费",
                    TotalFee = payFee
                });

            var payRequestParam = result.RequestHtml;

            return new CreatePrepayOrderResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                OrderId = newPrepayOrder.Id,
                OrderNo = newPrepayOrder.OrderNo,
                PayString = payRequestParam
            };
        }

        /// <summary>
        /// 用户取消支付
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("PayFailed")]
        public PayFailedResponse PayFailed(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);

            var order = _ctx.InpatientPrepayOrders.IsStatus(PrepayOrderExtensions.OrderStatus.支付中)
                .FirstOrDefault(x => x.OpenId == azUser.OpenId && x.Id == orderId);
            if (order == null)
            {
                return new PayFailedResponse
                {
                    ResultCode = "1",
                    ResultMsg = "订单不存在"
                };
            }

            order.OrderStatus = PrepayOrderExtensions.OrderStatus.支付失败.ToInt32();
            _ctx.SaveChanges();

            return new PayFailedResponse
            {
                ResultCode = "0",
                ResultMsg = ""
            };
        }

        /// <summary>
        /// 微信支付通知回调
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [ActionName("PaySucceed")]
        public HttpResponseMessage PaySucceed()
        {

            Dictionary<string, string> sPara = AlipayNotifyHelper.GetRequestPost();
            string sign = HttpContext.Current.Request.Form["sign"];
            var result =
                WapPayment.WapPayVerifyNotify(new WapPayVerifyNotifyRequest
                {
                    SPara = sPara,
                    Sign = sign
                });

            if (result != null && result.ResultCode == "0")
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(result.NotifyData);
                string transactionId = xmlDoc.SelectSingleNode("/notify/trade_no")?.InnerText ?? "";
                string trade_status = xmlDoc.SelectSingleNode("/notify/trade_status")?.InnerText ?? "";
                string notify_id = xmlDoc.SelectSingleNode("/notify/notify_id")?.InnerText ?? "";
                var outTradeNo = xmlDoc.SelectSingleNode("/notify/out_trade_no")?.InnerText ?? "";
                decimal total_fee = (xmlDoc.SelectSingleNode("/notify/total_fee")?.InnerText).ToDecimalOrDefault();
                string buyer_id = xmlDoc.SelectSingleNode("/notify/buyer_id")?.InnerText ?? "";
                string timeEnd = xmlDoc.SelectSingleNode("/notify/gmt_payment")?.InnerText;
                string seller_email = xmlDoc.SelectSingleNode("/notify/seller_email")?.InnerText;

                lock (PayNotifyLocker)
                {
                    try
                    {
                        if (_ctx.WxPayNotifyLogs.Any(
                            x => x.TransactionId == transactionId && x.TradeState == 1))
                        {
                            return new HttpResponseMessage
                            {
                                StatusCode = HttpStatusCode.OK,
                                Content = new StringContent("success")
                            };
                        }
                        else
                        {

                            if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                            {
                                if (outTradeNo.StartsWith("IP"))
                                {
                                    var orderNo = outTradeNo.Substring(2);
                                    var order = _ctx.InpatientPrepayOrders.FirstOrDefault(x => x.OrderNo == orderNo);
                                    if (order != null)
                                    {
                                        if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.支付中.ToInt32())
                                        {
                                            order.PayState = PrepayOrderExtensions.PayState.已付款.ToInt32().ToString();
                                            order.PayTime = timeEnd.ToDateTimeOrDefault();
                                            order.WxTransactionId = transactionId;
                                            order.OrderStatus = PrepayOrderExtensions.OrderStatus.支付成功.ToInt32();
                                            _ctx.SaveChanges();

                                            // RMQ 执行缴纳预缴金操作
                                            var pickupingProducer = new OrderPickupingProducer();
                                            pickupingProducer.Publish(new OrderPickupingMsg
                                            {
                                                OrderType = OrderType.住院预缴金订单,
                                                OrderId = order.Id
                                            });
                                        }
                                        else if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.缴费失败.ToInt32())
                                        {
                                            //His缴费失败，执行退款操作
                                            var refundingProducer = new OrderRefundingPickupFailedProducer();
                                            refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                            {
                                                OrderType = OrderType.住院预缴金订单,
                                                OrderId = order.Id
                                            });
                                        }
                                    }
                                }
                            }

                            #region 记录通过验证的支付通知

                            //记录通知日志
                            var orderNotifyLog = new WxPayNotifyLog
                            {
                                ServiceVersion = "2.0",
                                Attach = "",
                                BankBillNo = "",
                                BankType = "AliPay",
                                BuyerAlias = "",
                                Discount = 0,
                                FeeType = 1,
                                InputCharset = "utf-8",
                                NotifyId = notify_id,
                                SignType = "0001",
                                Sign = "", //Request.Form["sign"],
                                SignKeyIndex = 0,
                                TradeMode = 1,
                                PayInfo = "",
                                //Partner = xmlDoc.SelectSingleNode("/notify/seller_id").InnerText,
                                TotalFee = (total_fee * 100).ToInt32OrDefault(),
                                TransactionId = transactionId,
                                OutTradeNo = outTradeNo,
                                //TimerEnd = xmlDoc.SelectSingleNode("/notify/gmt_payment").InnerText,
                                TransportFee = 0,
                                ProductFee = (total_fee * 100).ToInt32OrDefault(),
                                PostAppId = seller_email,
                                PostTimeStamp = timeEnd,
                                PostNonceStr = "",
                                PostOpenId = buyer_id,
                                PostAppSignature = trade_status,
                                PostIsSubscribe = "1",
                                RecCreateDt = DateTime.Now
                            };
                            if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                                orderNotifyLog.TradeState = 1;
                            _ctx.WxPayNotifyLogs.Add(orderNotifyLog);
                            _ctx.SaveChanges();

                            #endregion

                            return new HttpResponseMessage
                            {
                                StatusCode = HttpStatusCode.OK,
                                Content = new StringContent("success")
                            };
                        }
                    }
                    catch (System.Data.SqlClient.SqlException sqlEx)
                    {
                        Logger.ErrorFormat("Inpatient PaySuccessed SqlException Error:{0}",
                            JsonConvert.SerializeObject(sqlEx));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorFormat("Inpatient PaySuccessed Error:{0}", JsonConvert.SerializeObject(e));

                    }
                }
            }

            #region 记录验证失败的支付通知

            var unverifiedNotifyLog = new WxPayNotifyLog();
            //unverifiedNotifyLog.PayInfo = Request.RequestUri.AbsoluteUri;
            unverifiedNotifyLog.TradeState = 0;
            unverifiedNotifyLog.RecCreateDt = DateTime.Now;
            _ctx.WxPayNotifyLogs.Add(unverifiedNotifyLog);
            _ctx.SaveChanges();

            #endregion

            return new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("fail")
            };
        }

        /// <summary>
        /// 获取预缴金缴纳状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetPrepayStatus")]
        public GetPrepayStatusResponse GetPrepayStatus(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            var order = _ctx.InpatientPrepayOrders.FirstOrDefault(x => x.Id == orderId && x.OpenId == azUser.OpenId);
            if (order == null)
            {
                return new GetPrepayStatusResponse
                {
                    ResultCode = "1",
                    ResultMsg = "订单不存在"
                };
            }

            if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.缴费中.ToInt32()
                || order.OrderStatus == PrepayOrderExtensions.OrderStatus.支付中.ToInt32()
                || order.OrderStatus == PrepayOrderExtensions.OrderStatus.支付成功.ToInt32())
            {
                return new GetPrepayStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    PrepayStatus = "2",
                    FailedMsg = ""
                };
            }

            if (order.OrderStatus == PrepayOrderExtensions.OrderStatus.缴费成功.ToInt32())
            {
                return new GetPrepayStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    PrepayStatus = "0",
                    FailedMsg = ""
                };
            }

            return new GetPrepayStatusResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                PrepayStatus = "1",
                FailedMsg = ""
            };
        }

        public static string GenerateNewOrderNo()
        {
            var orderNo = "AL" + DateTime.Now.Date.ToString("yyyyMMdd");
            lock (OrderNoLocker)
            {
                orderNo += (DateTime.Now - DateTime.Now.Date).TotalMilliseconds.ToString("00000000");
                Thread.Sleep(1);
            }

            return orderNo;
        }

        public string GetClientIp()
        {
            if (Request.Properties.ContainsKey("MS_HttpContext"))
            {
                string ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                //判断是否有代理服务器
                if (string.IsNullOrEmpty(ip))
                {
                    //没有代理服务器,如果有代理服务器获取的是代理服务器的IP
                    ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                string pattrn = @"(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])";
                if (!string.IsNullOrEmpty(ip) && System.Text.RegularExpressions.Regex.IsMatch(ip, pattrn))
                {
                    return ip;
                }

                return "127.0.0.1";
            }
            else
            {
                return "127.0.0.1";
            }
        }
    }
}
